#include "effect.h"
#include "map.h"
#include "main.h"
#include "player.h"
#include "action.h"
#include "resources.h"

void effect_update (Effect* effect)
{
	if (effect->cooldown > 0) {
		effect->cooldown--;
		if (effect->frame_time > 0) {
			if ((--effect->frame_cooldown) <= 0) {
				effect->frame_cooldown = effect->frame_time;
				effect->bmp_x += effect->bmp_w;
			}
		}
	}
}

/**
 * Draw background effect graphics.
 * These effects will appear behind other graphics such as the player,
 * map decorations etc.
 * Single effects may have background and foreground portions.
 * Therefore, draw_bg and draw_fg are usually both called on one single
 * effect in one draw cycle.
 */
void effect_draw_bg (Effect* effect, BITMAP* target, int xoffset, int yoffset)
{
	int tx, ty;
	int sx, sy;
	
	switch (effect->type) {

	case EFFECT_BITMAP:
		break;
		
	case EFFECT_DMGTEXT:
		break;
		
	case EFFECT_STRIKE:
		tx = xoffset + effect->where.x * TILE_SIZE + TILE_SIZE/2 - SPRITE_W/2 + effect->offset_x;
		ty = yoffset + effect->where.y * TILE_SIZE + TILE_SIZE/2 - SPRITE_SIZE/2 - (SPRITE_H-SPRITE_SIZE) + effect->offset_y;
		sx = effect->bmp_x + effect->bmp_w/2 - SPRITE_W/2;
		sy = effect->bmp_h * (effect->dir-1) + effect->bmp_h/2 - SPRITE_SIZE/2 - (SPRITE_H-SPRITE_SIZE);
		masked_blit (effect->source, target, sx, sy, tx, ty, SPRITE_W, SPRITE_H);
		break;
		
	}
}

/**
 * Draw foreground effect graphics.
 * These effects appear in front of all other map objects.
 */
void effect_draw_fg (Effect* effect, BITMAP* target, int xoffset, int yoffset)
{
	int tx, ty;
	int txa[3], tya[3], sxa[3], sya[3];
	
	switch (effect->type) {

	case EFFECT_BITMAP:
		tx = xoffset + effect->where.x * TILE_SIZE + TILE_SIZE/2 - effect->bmp_w/2 + effect->offset_x;
		ty = yoffset + effect->where.y * TILE_SIZE + TILE_SIZE/2 - effect->bmp_h/2 + effect->offset_y;
		masked_blit (effect->source, target, effect->bmp_x, effect->bmp_y, tx, ty, effect->bmp_w, effect->bmp_h);
		break;
		
	case EFFECT_DMGTEXT:
		tx = xoffset + effect->where.x * TILE_SIZE + effect->offset_x;
		ty = yoffset + effect->where.y * TILE_SIZE + effect->offset_y - (EFFECT_COOLDOWN_DAMAGE - effect->cooldown);
		clear_to_color (bmp.strtemp, makeacol (0,0,0,0));
		
		textout_ex(buffer, effect->font, effect->string, tx, ty, -1, -1);
			//makeacol (255, 0, 0, effect->cooldown * 255 / EFFECT_COOLDOWN_DAMAGE), -1);
		//drawing_mode (DRAW_MODE_TRANS, NULL, 0, 0);
		//draw_trans_sprite (buffer, bmp.strtemp, tx, ty);
		//drawing_mode (DRAW_MODE_SOLID, NULL, 0, 0);
		break;
		
	case EFFECT_STRIKE:
		// Drawing STRIKE foreground effects:
		// We need to draw everything around the player sprite, so the 
		// effect bitmap is split into 4 parts:
		//  +--------------+
		//  |       1      |
		//  +---+------+---+
		//  | 2 |SPRITE| 3 |
		//  +---+------+---+
		//  |       4      |
		//  +--------------+
		// Note: The lower 8 pixels of the player sprite 
		//       (i.e. its feet) are considered part of area 4.
		// The part of the effect that overlaps with the player sprite 
		// is drawn in effect_draw_bg.
		txa[0] = xoffset + effect->where.x * TILE_SIZE + TILE_SIZE/2 - effect->bmp_w/2 + effect->offset_x;
		txa[1] = xoffset + effect->where.x * TILE_SIZE + TILE_SIZE/2 - SPRITE_W/2 + effect->offset_x;
		txa[2] = xoffset + effect->where.x * TILE_SIZE + TILE_SIZE/2 + SPRITE_W/2 + effect->offset_x;
		tya[0] = yoffset + effect->where.y * TILE_SIZE + TILE_SIZE/2 - effect->bmp_h/2 + effect->offset_y;
		tya[1] = yoffset + effect->where.y * TILE_SIZE + TILE_SIZE/2 - SPRITE_SIZE/2 - (SPRITE_H-SPRITE_SIZE) + effect->offset_y;
		tya[2] = yoffset + effect->where.y * TILE_SIZE + TILE_SIZE/2 + effect->offset_y;
		sxa[0] = effect->bmp_x;
		sxa[1] = effect->bmp_x + effect->bmp_w/2 - SPRITE_W/2;
		sxa[2] = effect->bmp_x + effect->bmp_w/2 + SPRITE_W/2;
		sya[0] = effect->bmp_h * (effect->dir-1);
		sya[1] = effect->bmp_h * (effect->dir-1) + effect->bmp_h/2 - SPRITE_SIZE/2 - (SPRITE_H-SPRITE_SIZE);
		sya[2] = effect->bmp_h * (effect->dir-1) + effect->bmp_h/2;
		
		masked_blit (effect->source, target, sxa[0], sya[0], txa[0], tya[0], effect->bmp_w, sya[1] - sya[0]);
		masked_blit (effect->source, target, sxa[0], sya[1], txa[0], tya[1], sxa[1] - sxa[0], SPRITE_H);
		masked_blit (effect->source, target, sxa[2], sya[1], txa[2], tya[1], effect->bmp_w - (sxa[2] - effect->bmp_x), SPRITE_H);
		masked_blit (effect->source, target, sxa[0], sya[2], txa[0], tya[2], effect->bmp_w, effect->bmp_h - (sya[2] - effect->bmp_h * (effect->dir-1)));
		break;
		
	}
}

Effect effect_make_weapon (BITMAP* sheet, Direction dir, coord_t where)
{
	return (Effect) {
		EFFECT_STRIKE, // type
		sheet,      // source
		NULL, {}, // font, string
		0, 0, 64, 64, // bmp_xywh
		where,      // where
		0, 0, // offset_x, offset_y
		COOLDOWN_ATTACK,   // cooldown
		COOLDOWN_ATTACK/3, // frame_time
		COOLDOWN_ATTACK/3, // frame_cooldown
		dir
	};
}

Effect effect_make_damage (FONT* font, const char* string, coord_t where)
{
	Effect e = {
		EFFECT_DMGTEXT,
		NULL,
		font, {},
		0, 0, 0, 0,
		where,
		0, 0,
		EFFECT_COOLDOWN_DAMAGE,
		0, 0,
		DIR_NONE
	};
	memset (e.string, 0, EFFECT_TEXTLEN * sizeof(char));
	strncpy (e.string, string, EFFECT_TEXTLEN-1);
	return e;
}
